package com.lineage.server.model.Instance;

import com.lineage.config.ConfigAlt;
import com.lineage.config.ConfigRate;
import com.lineage.server.datatables.NPCTalkDataTable;
import com.lineage.server.model.L1AttackPc;
import com.lineage.server.model.L1Character;
import com.lineage.server.model.L1NpcTalkData;
import com.lineage.server.model.L1Object;
import com.lineage.server.model.drop.DropShare;
import com.lineage.server.serverpackets.S_ChangeHeading;
import com.lineage.server.serverpackets.S_DoActionGFX;
import com.lineage.server.serverpackets.S_NPCTalkReturn;
import com.lineage.server.serverpackets.S_NpcChat;
import com.lineage.server.serverpackets.S_NpcChatShouting;
import com.lineage.server.serverpackets.S_ServerMessage;
import com.lineage.server.serverpackets.ServerBasePacket;
import com.lineage.server.templates.L1Npc;
import com.lineage.server.thread.GeneralThreadPool;
import com.lineage.server.types.Point;
import com.lineage.server.utils.CalcExp;
import com.lineage.server.world.World;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Random;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class L1GuardianInstance extends L1NpcInstance {
  private static final long serialVersionUID = 1L;
  
  private static final Log _log = LogFactory.getLog(L1GuardianInstance.class);
  
  private Random _random;
  
  private L1GuardianInstance _npc;
  
  private static final int COUNT_PAN = 50;
  
  private static final int TIME_PAN = 20;
  
  private static final int COUNT_PAN1 = 50;
  
  private static final int TIME_PAN1 = 20;
  
  private static final int TIME_ONTER1 = 1;
  
  private static final int TIME_ONTER2 = 40;
  
  private static final int TIME_ONTER3 = 10;
  
  public L1GuardianInstance(L1Npc template) {
    super(template);
    this._random = new Random();
    this._npc = this;
    int npcid = getNpcTemplate().get_npcId();
    switch (npcid) {
      case 70850:
        getInventory().storeItem(40519, 50L);
        break;
      case 70846:
        getInventory().storeItem(40503, 50L);
        break;
      case 70848:
        getInventory().storeItem(40506, 1L);
        getInventory().storeItem(40507, 40L);
        getInventory().storeItem(40505, 10L);
        break;
    } 
  }
  
  public void searchTarget() {
    L1PcInstance targetPlayer = searchTarget(this);
    if (targetPlayer != null) {
      this._hateList.add(targetPlayer, 0);
      this._target = targetPlayer;
    } 
  }
  
  private static L1PcInstance searchTarget(L1GuardianInstance npc) {
    L1PcInstance targetPlayer = null;
    Iterator<L1PcInstance> iterator = World.get().getVisiblePlayer((L1Object)npc).iterator();
    while (iterator.hasNext()) {
      L1PcInstance pc = iterator.next();
      try {
        Thread.sleep(10L);
      } catch (InterruptedException e) {
        _log.error(e.getLocalizedMessage(), e);
      } 
      if (pc.getCurrentHp() <= 0 || pc.isDead() || pc.isGm() || 
        pc.isGhost())
        continue; 
      if (pc.isInvisble() && !npc.getNpcTemplate().is_agrocoi())
        continue; 
      if (!pc.isElf()) {
        targetPlayer = pc;
        npc.wideBroadcastPacket((ServerBasePacket)new S_NpcChatShouting(npc, "$804"));
        break;
      } 
      if (pc.isElf() && pc.isWantedForElf()) {
        targetPlayer = pc;
        npc.wideBroadcastPacket((ServerBasePacket)new S_NpcChat(npc, "$815"));
        break;
      } 
    } 
    return targetPlayer;
  }
  
  public void setLink(L1Character cha) {
    if (cha != null && this._hateList.isEmpty()) {
      this._hateList.add(cha, 0);
      checkTarget();
    } 
  }
  
  public void onNpcAI() {
    if (isAiRunning())
      return; 
    setActived(false);
    startAI();
  }
  
  public void onAction(L1PcInstance player) {
    try {
      if (player.getType() == 2 && player.getCurrentWeapon() == 0 && player.isElf()) {
        L1AttackPc l1AttackPc = new L1AttackPc(player, this);
        if (l1AttackPc.calcHit()) {
          if (getNpcTemplate().get_npcId() == 70848 && hasSkillEffect(9002) && 
            hasSkillEffect(9003) && hasSkillEffect(9004)) {
            broadcastPacketX10((ServerBasePacket)new S_NpcChatShouting(this, "我已经没有东西了,稍后在来吧。"));
            return;
          } 
          if (getNpcTemplate().get_npcId() == 70848 && !hasSkillEffect(9002)) {
            int chance = this._random.nextInt(100) + 1;
            if (chance <= 2)
              if (getInventory().consumeItem(40506, 1L)) {
                player.getInventory().storeItem(40506, 1L);
                player.sendPackets((ServerBasePacket)new S_ServerMessage(143, "$755", "$794"));
              } else {
                setSkillEffect(9002, 1200000);
                getInventory().storeItem(40506, 1L);
              }  
          } 
          if (getNpcTemplate().get_npcId() == 70848 && !hasSkillEffect(9003)) {
            int chance = this._random.nextInt(100) + 1;
            if (chance <= 20)
              if (getInventory().consumeItem(40507, 1L)) {
                player.getInventory().storeItem(40507, 1L);
                player.sendPackets((ServerBasePacket)new S_ServerMessage(143, "$755", "$763"));
              } else {
                setSkillEffect(9003, 1200000);
                getInventory().storeItem(40507, 40L);
              }  
          } 
          if (getNpcTemplate().get_npcId() == 70848 && !hasSkillEffect(9004)) {
            int chance = this._random.nextInt(100) + 1;
            if (chance <= 20)
              if (getInventory().consumeItem(40505, 1L)) {
                player.getInventory().storeItem(40505, 1L);
                player.sendPackets((ServerBasePacket)new S_ServerMessage(143, "$755", "$770"));
              } else {
                setSkillEffect(9004, 1200000);
                getInventory().storeItem(40505, 10L);
              }  
          } 
          if (getNpcTemplate().get_npcId() == 70850)
            if (hasSkillEffect(9000)) {
              broadcastPacketX10((ServerBasePacket)new S_NpcChatShouting(this, "$824"));
            } else {
              int chance = this._random.nextInt(100) + 1;
              if (chance <= 30)
                if (getInventory().consumeItem(40519, 5L)) {
                  player.getInventory().storeItem(40519, 5L);
                  player.sendPackets((ServerBasePacket)new S_ServerMessage(143, "$753", "$760 (5)"));
                } else {
                  setSkillEffect(9000, 1200000);
                  broadcastPacketX10((ServerBasePacket)new S_NpcChatShouting(this, "$824"));
                  getInventory().storeItem(40519, 50L);
                }  
            }  
          if (getNpcTemplate().get_npcId() == 70846)
            if (hasSkillEffect(9001)) {
              broadcastPacketX10((ServerBasePacket)new S_NpcChatShouting(this, "$823"));
            } else {
              L1ItemInstance item = getInventory().findItemId(40507);
              if (item != null) {
                long count = item.getCount() >> 1L;
                if (getInventory().checkItem(item, count * 2L)) {
                  getInventory().removeItem(item, count * 2L);
                  if (getInventory().consumeItem(40503, 1L)) {
                    player.getInventory().storeItem(40503, 1L);
                    player.sendPackets((ServerBasePacket)new S_ServerMessage(143, "$752", "$769"));
                  } else {
                    setSkillEffect(9001, 1200000);
                    getInventory().storeItem(40503, 50L);
                  } 
                } 
              } 
            }  
        } 
        l1AttackPc.calcDamage();
        l1AttackPc.action();
        l1AttackPc.commit();
      } else if (getCurrentHp() > 0 && !isDead()) {
        L1AttackPc l1AttackPc = new L1AttackPc(player, this);
        if (l1AttackPc.calcHit())
          l1AttackPc.calcDamage(); 
        l1AttackPc.action();
        l1AttackPc.commit();
      } 
    } catch (Exception e) {
      _log.error(e.getLocalizedMessage(), e);
    } 
  }
  
  public void onTalkAction(L1PcInstance player) {
    int objid = getId();
    L1NpcTalkData talking = NPCTalkDataTable.get().getTemplate(getNpcTemplate().get_npcId());
    L1Object object = World.get().findObject(getId());
    L1NpcInstance target = (L1NpcInstance)object;
    if (talking != null) {
      int pcx = player.getX();
      int pcy = player.getY();
      int npcx = target.getX();
      int npcy = target.getY();
      if (pcx == npcx && pcy < npcy) {
        setHeading(0);
      } else if (pcx > npcx && pcy < npcy) {
        setHeading(1);
      } else if (pcx > npcx && pcy == npcy) {
        setHeading(2);
      } else if (pcx > npcx && pcy > npcy) {
        setHeading(3);
      } else if (pcx == npcx && pcy > npcy) {
        setHeading(4);
      } else if (pcx < npcx && pcy > npcy) {
        setHeading(5);
      } else if (pcx < npcx && pcy == npcy) {
        setHeading(6);
      } else if (pcx < npcx && pcy < npcy) {
        setHeading(7);
      } 
      broadcastPacketAll((ServerBasePacket)new S_ChangeHeading(this));
      if (player.getLawful() < -1000) {
        player.sendPackets((ServerBasePacket)new S_NPCTalkReturn(talking, objid, 2));
      } else {
        player.sendPackets((ServerBasePacket)new S_NPCTalkReturn(talking, objid, 1));
      } 
      set_stop_time(10);
      setRest(true);
    } 
  }
  
  public void receiveDamage(L1Character attacker, int damage) {
    this.ISASCAPE = false;
    if (attacker instanceof L1PcInstance && damage > 0) {
      L1PcInstance pc = (L1PcInstance)attacker;
      if (pc.getType() != 2 || pc.getCurrentWeapon() != 0)
        if (getCurrentHp() > 0 && !isDead()) {
          if (damage >= 0 && !(attacker instanceof L1EffectInstance))
            if (attacker instanceof L1IllusoryInstance) {
              L1IllusoryInstance ill = (L1IllusoryInstance)attacker;
              attacker = ill.getMaster();
              setHate(attacker, damage);
            } else {
              setHate(attacker, damage);
            }  
          if (damage > 0)
            removeSkillEffect(66); 
          onNpcAI();
          serchLink(pc, getNpcTemplate().get_family());
          if (damage > 0)
            pc.setPetTarget(this); 
          int newHp = getCurrentHp() - damage;
          if (newHp <= 0 && !isDead()) {
            setCurrentHpDirect(0);
            setDead(true);
            setStatus(8);
            Death death = new Death(attacker);
            GeneralThreadPool.get().execute(death);
          } 
          if (newHp > 0)
            setCurrentHp(newHp); 
        } else if (!isDead()) {
          setDead(true);
          setStatus(8);
          Death death2 = new Death(attacker);
          GeneralThreadPool.get().execute(death2);
        }  
    } 
  }
  
  public void setCurrentHp(int i) {
    int currentHp = Math.min(i, getMaxHp());
    if (getCurrentHp() == currentHp)
      return; 
    setCurrentHpDirect(currentHp);
  }
  
  public void setCurrentMp(int i) {
    int currentMp = Math.min(i, getMaxMp());
    if (getCurrentMp() == currentMp)
      return; 
    setCurrentMpDirect(currentMp);
  }
  
  public void onFinalAction(L1PcInstance player, String action) {}
  
  public void doFinalAction(L1PcInstance player) {}
  
  class Death implements Runnable {
    L1Character _lastAttacker;
    
    public Death(L1Character lastAttacker) {
      this._lastAttacker = lastAttacker;
    }
    
    public void run() {
      L1GuardianInstance.this.setDeathProcessing(true);
      L1GuardianInstance.this.setCurrentHpDirect(0);
      L1GuardianInstance.this.setDead(true);
      L1GuardianInstance.this.setStatus(8);
      int targetobjid = L1GuardianInstance.this.getId();
      L1GuardianInstance.this.getMap().setPassable((Point)L1GuardianInstance.this.getLocation(), true);
      L1GuardianInstance.this.broadcastPacketAll((ServerBasePacket)new S_DoActionGFX(targetobjid, 8));
      L1PcInstance player = null;
      if (this._lastAttacker instanceof L1PcInstance) {
        player = (L1PcInstance)this._lastAttacker;
      } else if (this._lastAttacker instanceof L1PetInstance) {
        player = (L1PcInstance)((L1PetInstance)this._lastAttacker).getMaster();
      } else if (this._lastAttacker instanceof L1SummonInstance) {
        player = (L1PcInstance)((L1SummonInstance)this._lastAttacker).getMaster();
      } else if (this._lastAttacker instanceof L1IllusoryInstance) {
        player = (L1PcInstance)((L1IllusoryInstance)this._lastAttacker).getMaster();
      } else if (this._lastAttacker instanceof L1EffectInstance) {
        player = (L1PcInstance)((L1EffectInstance)this._lastAttacker).getMaster();
      } 
      if (player != null) {
        ArrayList<L1Character> targetList = L1GuardianInstance.this._hateList.toTargetArrayList();
        ArrayList<Integer> hateList = L1GuardianInstance.this._hateList.toHateArrayList();
        long exp = L1GuardianInstance.this.getExp();
        CalcExp.calcExp(player, targetobjid, targetList, hateList, exp);
        ArrayList<L1Character> dropTargetList = L1GuardianInstance.this._dropHateList.toTargetArrayList();
        ArrayList<Integer> dropHateList = L1GuardianInstance.this._dropHateList.toHateArrayList();
        try {
          DropShare dropShare = new DropShare();
          dropShare.dropShare(L1GuardianInstance.this._npc, dropTargetList, dropHateList);
        } catch (Exception e) {
          L1GuardianInstance._log.error(e.getLocalizedMessage(), e);
        } 
        player.addKarma((int)(L1GuardianInstance.this.getKarma() * ConfigRate.RATE_KARMA));
      } 
      L1GuardianInstance.this.setDeathProcessing(false);
      L1GuardianInstance.this.setKarma(0);
      L1GuardianInstance.this.setExp(0L);
      L1GuardianInstance.this.allTargetClear();
      L1GuardianInstance.this.startDeleteTimer(ConfigAlt.NPC_DELETION_TIME);
    }
  }
}
